//
//  OPBoardStructure.m
//  OPFramework
//
//  Created by malcom on 7/13/08.
//  Copyright 2008 malcom-mac software. All rights reserved.
//

#import "OPBoardStructure.h"
#import "OPBoard.h"

typedef enum OPBoardStructure_Find_What {
    OPBoardStructure_Find_What_ForID		= 0,
    OPBoardStructure_Find_What_ForName		= 1
} OPBoardStructure_Find_What;


@implementation OPBoardStructure

@synthesize _rootNode;

- (id) initWithBoard:(OPBoard *) _board {
	self = [super initWithBoard: _board];
	if (self != nil) {		
		// load board structure, if something went wrong we return nil
		if (! [self loadData])
			return nil;
	}
	return self;
}

- (BOOL) loadData {
	NSArray *params = (_delegateBoard.obj_authUser.user_loginDate == nil ? nil : 
					   [[NSArray arrayWithObject: 
						 [NSNumber numberWithLongLong: [_delegateBoard.obj_authUser.user_loginDate timeIntervalSince1970]]] retain]);

	
	BOOL ok = [self sendXMLRequestForMethod: @"msgs.getForumsTree" withParams:params parseSelector:@selector(_loadStructure:) forceSyncRequest: NO];
	return ok;
	
	/*
	XMLRPCResponse *rsp = [_delegateBoard _executeRequestMethodNamed: @"msgs.getForumsTree" 
														  withParams:params];
	[params release];
	BOOL resultOK = ([rsp isFault] == NO);
	
	if (resultOK) { // ok received structure
		NSMutableDictionary *_struct= [[NSMutableDictionary alloc] initWithDictionary: [rsp responseObject]];
		// load structure
		[self _loadStructure: _struct];
		
		// release struct dictionary
		[_struct release];
	}
	
	NSLog(@"Loading board structure for '%@'... %@",[_delegateBoard.obj_boardConfig getPropertyForKey: OPBoardConfig_Sitename],(resultOK ? @"OK" : @"FAILED"));
	
	return resultOK;*/
	
}

- (void)connection: (XMLRPCConnection *)connection didReceiveResponse:(XMLRPCResponse *)response forMethod: (NSString *)method {
	// super class check if it's an error, a numeric response or simply some data to parse
	if (![self _checkErrorInRawResponseFromServer: response forMethod:method]) {
		// data update to parse
		[self _loadStructure: [NSArray arrayWithObjects: [response responseObject],method,nil]];
		// we can propagate the result to listeners
		[self dataUpdatedFor: self atMethod:method];	
	}
}

- (BOOL) _isNumericResponseFromServerAnErrorCode:(NSNumber *) _code forMethod:(NSString *) method {
	return NO;
}

- (void) _loadStructure:(NSArray *) _result {
	NSDictionary *_dict = (NSDictionary*)[_result objectAtIndex:0];
	// init the root point node
	if (_rootNode != nil) [_rootNode release];
	_rootNode = [[OPForum alloc] initWithForumID: 0 ofBoard: _delegateBoard];
	// iterative cycle to load forums
	[self _loadObject: _dict asChildOf: _rootNode];
}

- (void) _loadObject:(NSDictionary *) _fList asChildOf:(OPForum *) _forum {
	for (NSString *cForumKey in _fList) {
		NSDictionary *cForum = [_fList objectForKey: cForumKey];
		// alloc object
		OPForum *oObj = [[[OPForum alloc] initByLoadingPropertiesDictionary: cForum
																  fromBoard:_delegateBoard] autorelease];
		
		
		// add to childs
		[_forum._childs addObject: oObj];
		
		// search for childs
		if ([[cForum objectForKey: _OPForum_Childs] count] > 0)
			[self _loadObject: [cForum objectForKey: _OPForum_Childs] asChildOf: oObj];
	}
	
}

- (OPForum *) getForumFromID:(NSNumber *) _id {
	if ([_id intValue] == 0) return _rootNode; // forum id = 0 means announcements. we will put announcements in rootnode so we will return it
	OPForum *_targetForum = [self _getForumSearchByWhat: OPBoardStructure_Find_What_ForID withValue: _id inList: _rootNode._childs];
	return _targetForum;
}

- (OPForum *) getForumFromName:(NSString *) _name {
	OPForum *_targetForum = [self _getForumSearchByWhat: OPBoardStructure_Find_What_ForName withValue:_name inList: _rootNode._childs];
	return _targetForum;
}

- (OPForum *) _getForumSearchByWhat:(int) _type withValue:(id) _value inList:(NSArray *) _list {
	for (OPForum *cForum in _list) {
		BOOL isFound = NO;
		switch (_type) {
			case OPBoardStructure_Find_What_ForName:
				isFound = [cForum.p_forumName isEqualToString: ((NSString *)_value)]; break;
			case OPBoardStructure_Find_What_ForID:
				isFound = cForum._forumID == [((NSNumber*)_value) intValue]; break;
		}
		
		if (isFound)
			return cForum;
		else if ([cForum._childs count] > 0) {
			OPForum *cFoundInside = [self _getForumSearchByWhat: _type withValue: _value inList: cForum._childs];
			if (cFoundInside != nil) return cFoundInside;
		}
	}
	return nil;
}

- (void) dealloc {
	[_rootNode release];
	[super dealloc];
}

- (NSArray *) getFlatNormalForumsList {
	NSMutableArray *_finalList = [[NSMutableArray alloc] init];
	// adding forum list
	[self _browseForum: _rootNode._childs addingForumTo: _finalList];
	
	return [_finalList autorelease];
}

- (void) _browseForum:(NSArray *) _list addingForumTo:(NSMutableArray *) _finalList {
	for (OPForum *cForum in _list) {
		if ([cForum.p_forumType intValue] == OPForum_Type_NormalForum)
			[_finalList addObject: cForum];
		
		if ([cForum._childs count] > 0)
			[self _browseForum: cForum._childs addingForumTo: _finalList];
	}
}

@end
